/***********************************************************
File name     : xjson.h
Author name   : lancz
Email address : chengzhang.lan@jointlighting.com
Create time   : 2022-09-14 09:28:30
***********************************************************/
#ifndef __XJSON_H__
#define __XJSON_H__

#include <stdlib.h>
#include <ctype.h>
#include "rtdef.h"
#ifdef __linux__
#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
#elif defined(RT_USED)
#include <dfs_posix.h>
#endif

#include "cJSON.h"
#include "xstddef.h"

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#define XJSON_MAX_PATH_LENGTH 256

typedef cJSON *xt_json;

#define XjsonCreateObject() cJSON_CreateObject()
#define XjsonDup(obj) cJSON_Duplicate(obj, XTRUE)
#define XjsonDelete(obj) cJSON_Delete(obj)
#define XjsonToString(obj) cJSON_PrintUnformatted(obj)
#define XjsonToStringPretty(obj) cJSON_Print(obj)
#define XjsonFromString(str) cJSON_Parse(str)
#define XjsonValue(obj, key) cJSON_GetObjectItem(obj, key)
#define XjsonArraySize(obj) cJSON_GetArraySize(obj)

#define XjsonCreateArray() cJSON_CreateArray()
#define XjsonArrayAddItem(item) cJSON_AddItemToArray(item)
#define XjsonObjectAddItem(parent, key, item) cJSON_AddItemToObject(parent, key, item)

xt_json XjsonNewIntFmt(xt_rostring path_fmt, xt_s32 value, ...);
xt_json XjsonNewStringFmt(xt_rostring path_fmt, xt_rostring value, ...);
xt_json XjsonNewInt(xt_rostring path_fmt, xt_s32 value);
xt_json XjsonNewDouble(xt_rostring path_fmt, double value);
xt_json XjsonNewDoubleFmt(xt_rostring path_fmt, double value, ...);
xt_json XjsonNewString(xt_rostring path_fmt, xt_rostring value);
xt_json XjsonNewBool(xt_rostring path_fmt, xt_bool value);
xt_s32 XjsonQueryBool(xt_json root, xt_rostring path, xt_bool *value);
xt_json XjsonNewBoolFmt(xt_rostring path_fmt, xt_bool value, ...);
xt_json XjsonNewBinary(xt_rostring path, void *value, xt_s32 size);
xt_json XjsonNewBinaryFmt(xt_rostring path_fmt, void *value, xt_s32 size, ...);
xt_s32 XjsonSetBinary(xt_json root, xt_rostring path, void *value, xt_s32 size);

xt_s32 XjsonParsePath(xt_rostring key,
                      xt_string parent_path, xt_s32 path_size,
                      xt_string key_name, xt_s32 key_size);
xt_json XjsonSearch(xt_json root, xt_rostring path);
xt_s32 XjsonLength(xt_json root, xt_rostring path);
xt_s32 XjsonKeysCount(xt_json root, xt_rostring path);
xt_s32 XjsonKeys(xt_json root,
                 xt_rostring path,
                 xt_string keys[],
                 xt_s32 maxsize);
xt_json XjsonSearchParent(xt_json root, xt_rostring path);
xt_json XjsonNewParent(xt_json root,
                       xt_rostring path,
                       xt_string node,
                       xt_s32 bufsize);

xt_s32 XjsonGetInt(xt_json root,
                   xt_rostring path,
                   xt_s32 *value,
                   xt_s32 defvalue);
xt_s32 XjsonGetString(xt_json root,
                      xt_rostring path,
                      xt_string value,
                      xt_s32 bufsize,
                      xt_rostring defvalue);
xt_s32 XjsonSetBool(xt_json root, xt_rostring path, xt_bool value);
xt_s32 XjsonSetInt(xt_json root, xt_rostring path, xt_s32 value);
xt_s32 XjsonSetIntFmt(xt_json root, xt_rostring path_fmt, xt_s32 value, ...);
xt_s32 XjsonSetDouble(xt_json root, xt_rostring path, double value);
xt_s32 XjsonSetString(xt_json root, xt_rostring path, xt_rostring value);
xt_s32 XjsonSetObject(xt_json root, xt_rostring path, xt_json value);

xt_s32 XjsonArrayAddObject(xt_json root, xt_rostring path, xt_json value);
xt_s32 XjsonArrayGetObject(xt_json root,
                           xt_rostring path,
                           xt_json values[],
                           xt_s32 maxsize);

xt_s32 XjsonArrayAppendInt(xt_json root, xt_rostring path, xt_s32 value);
xt_s32 XjsonArrayAddInt(xt_json root, xt_rostring path, xt_s32 value);
xt_s32 XjsonArrayGetInt(xt_json root,
                        xt_rostring path,
                        xt_s32 values[],
                        xt_s32 maxsize);
xt_s32 XjsonArrayGetIntIndex(xt_json root, xt_rostring path, xt_s32 value);
xt_s32 XjsonArrayRemoveInt(xt_json root, xt_rostring path, xt_s32 value);

xt_s32 XjsonArrayAddString(xt_json root, xt_rostring path, xt_rostring value);
xt_s32 XjsonArrayAppendString(xt_json root, xt_rostring path, xt_rostring value);
xt_s32 XjsonArrayGetStringIndex(xt_json root, xt_rostring path, xt_rostring value);
xt_s32 XjsonArrayGetString(xt_json root, xt_rostring path,
                           xt_string values[], xt_s32 maxsize);
xt_s32 XjsonQueryInt(xt_json root, xt_rostring path, xt_s32 *value);
xt_s32 XjsonQueryDouble(xt_json root, xt_rostring path, double *value);
xt_string XjsonQueryString(xt_json root, xt_rostring path);
xt_json XjsonQueryObject(xt_json root, xt_rostring path);
xt_s32 XjsonQueryBinary(xt_json root, xt_rostring path, void *buf, xt_s32 bufsize);

xt_s32 XjsonSetInt64(xt_json root, xt_rostring path, xt_s64 value);
xt_json XjsonNewInt64(xt_rostring path, xt_s64 value);
xt_s32 XjsonQueryInt64(xt_json root, xt_rostring path, xt_s64 *value);

xt_s32 XjsonArrayRemoveString(xt_json root, xt_rostring path, xt_rostring value);

xt_s32 XjsonArrayDeleteInt(xt_json root, xt_rostring path, xt_s32 value);
xt_s32 XjsonArrayDeleteIndex(xt_json root, xt_rostring path, xt_s32 index);
xt_s32 XjsonArrayDeleteString(xt_json root, xt_rostring path, xt_rostring value);
xt_json XjsonMerge(xt_json target, xt_json add);
xt_s32 XjsonRemove(xt_json root, xt_rostring path);
xt_s32 XjsonDump(xt_rostring msg, xt_json object);
xt_s32 XjsonDumpPretty(xt_rostring msg, xt_json object);
#define XjsonDebugDump(msg, object)                  \
    do {                                             \
        xt_string objectStr = XjsonToString(object); \
        if (NULL == objectStr)                       \
            break;                                   \
        if (msg)                                     \
            XLOG_D("%s: %s", msg, objectStr);        \
        else                                         \
            XLOG_D("%s\n", objectStr);               \
        if (objectStr)                               \
            Xfree(objectStr);                        \
    } while (0)

xt_s32 XjsonArrayGetIntItem(xt_json array, xt_s32 index, xt_s32 *value);
xt_string XjsonArrayGetStringItem(xt_json array, xt_s32 index);
xt_s32 XjsonArrayGetDoubleItem(xt_json array, xt_s32 index, double *value);
xt_json XjsonArrayGetItem(xt_json array, xt_s32 index);

#ifdef RT_USED
#include "xfile.h"
xt_json XjsonLoad(xt_rostring path);
xt_s32 XjsonSave(xt_rostring path, xt_json json);
#endif

#ifdef __cplusplus
}
#endif // __cplusplus
#endif
